package com.android.kotlincoroutinemvvmdemo.view
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.MotionEvent
import com.android.kotlincoroutinemvvmdemo.R

/*
* BezierCubicToTestView
* */
class BezierCubicToTestView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : BaseView(context, attributeSet) {

    private val mPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            strokeCap = Paint.Cap.ROUND
            strokeJoin = Paint.Join.ROUND
            strokeWidth = context.resources.getDimension(R.dimen.dp_2)
            style = Paint.Style.STROKE
            color = context.resources.getColor(R.color.color_23F392)
        }
    }

    private val mPaint1 by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            color = context.resources.getColor(R.color.color_F13376)
        }
    }

    private val mPaint2 by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            textSize = context.resources.getDimension(R.dimen.sp_15)
            color = context.resources.getColor(R.color.color_03FADD)
        }
    }

    private val mPaint3 by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            strokeCap = Paint.Cap.ROUND
            strokeJoin = Paint.Join.ROUND
            strokeWidth = context.resources.getDimension(R.dimen.dp_2)
            style = Paint.Style.STROKE
            color = context.resources.getColor(R.color.color_A98DE8)
        }
    }

    private val mPaint5 by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            strokeWidth = context.resources.getDimension(R.dimen.dp_2)
            style = Paint.Style.STROKE
            color = context.resources.getColor(R.color.color_FF8A80)
        }
    }

    private val mPaint6 by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            strokeWidth = context.resources.getDimension(R.dimen.dp_2)
            style = Paint.Style.STROKE
            color = context.resources.getColor(R.color.color_FF80AB)
        }
    }

    private val mPath by lazy {
        Path()
    }

    private val label0 = "0"
    private val label1 = "1"
    private val label2 = "2"
    private val label3 = "3"

    private var mCx0 = 0F
    private var mCy0 = 0F

    private var mCx1 = -120F
    private var mCy1 = -150F

    private var mCx2 = 100F
    private var mCy2 = 0F

    private var mCx3 = 200F
    private var mCy3 = 200F

    private var currentSelect = 0x00

    private var widthHeight = 0

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        widthHeight = Math.min(mWidth, mHeight)
        setMeasuredDimension(widthHeight, widthHeight)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        setBackgroundColor(context.resources.getColor(R.color.color_F3F3F3))
        canvas?.apply {
            val cx = widthHeight.toFloat() / 2
            val cy = widthHeight.toFloat() / 2
            translate(cx, cy)

            drawLine(
                -cx,
                0F,
                cx,
                0F,
                mPaint
            )

            for (i in 9.downTo(1)) {
                drawLine(
                    -cx * i / 10,
                    -cy / 40,
                    -cx * i / 10,
                    0F,
                    mPaint
                )
            }

            for (i in 1..9) {
                drawLine(
                    cx * i / 10,
                    -cy / 40,
                    cx * i / 10,
                    0F,
                    mPaint
                )
            }

            drawLine(
                0F,
                -cy,
                0F,
                cy,
                mPaint
            )

            for (i in 9.downTo(1)) {
                drawLine(
                    cx / 40,
                    -cy * i / 10,
                    0F,
                    -cy * i / 10,
                    mPaint
                )
            }

            for (i in 1..9) {
                drawLine(
                    cx / 40,
                    cy * i / 10,
                    0F,
                    cy * i / 10,
                    mPaint
                )
            }


            mPath.apply {
                reset()
                moveTo(mCx0, mCx0)
                cubicTo(mCx1, mCy1, mCx2, mCy2, mCx3, mCy3)
            }
            drawPath(mPath, mPaint)

            drawCircle(
                mCx0,
                mCy0,
                cx / 10,
                mPaint1
            )


            val value0 = mPaint2.measureText(label0)
            drawText(label0, mCx0 - value0 / 2, mCy0 + value0 / 2, mPaint2)

            drawCircle(
                mCx1,
                mCy1,
                cx / 10,
                mPaint1
            )
            val value1 = mPaint2.measureText(label1)
            drawText(label1, mCx1 - value1 / 2, mCy1 + value1 / 2, mPaint2)

            drawCircle(
                mCx2,
                mCy2,
                cx / 10,
                mPaint1
            )
            val value2 = mPaint2.measureText(label2)
            drawText(label2, mCx2 - value2 / 2, mCy2 + value2 / 2, mPaint2)

            drawCircle(
                mCx3,
                mCy3,
                cx / 10,
                mPaint1
            )
            val value3 = mPaint2.measureText(label3)
            drawText(label3, mCx3 - value3 / 2, mCy3 + value3 / 2, mPaint2)

            drawRect(
                mCx0,
                mCy0,
                0F,
                0F,
                mPaint3
            )

            drawRect(
                mCx1,
                mCy1,
                0F,
                0F,
                mPaint3
            )

            drawRect(
                mCx2,
                mCy2,
                0F,
                0F,
                mPaint3
            )

            drawRect(
                mCx3,
                mCy3,
                0F,
                0F,
                mPaint3
            )

            drawCircle(
                0F,
                0F,
                cx * 3 / 10,
                mPaint5
            )

            drawCircle(
                0F,
                0F,
                cx * 6 / 10,
                mPaint6
            )
        }
    }

    override fun onTouchEvent(event: MotionEvent?) : Boolean {
        performClick()
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {}
            MotionEvent.ACTION_MOVE -> {
                val moveX = event.x - widthHeight.toFloat() / 2
                val moveY = event.y - widthHeight.toFloat() / 2
                when (currentSelect) {
                    0 -> {
                        mCx0 = moveX
                        mCy0 = moveY
                    }
                    1 -> {
                        mCx1 = moveX
                        mCy1 = moveY
                    }
                    2 -> {
                        mCx2 = moveX
                        mCy2 = moveY
                    }
                    3 -> {
                        mCx3 = moveX
                        mCy3 = moveY
                    }
                }
                invalidate()
            }
        }
        return true
    }

    fun updateSelect(select: Int) {
        this.currentSelect = select
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }
}